use warnings;
use strict;

my @LogType = ('', 'ERROR', 'WARNING', 'INFO', 'DETAIL', 'DEBUG');
my @LogChar = ('', 'E', 'W', 'I', 'D', 'G');

sub GetVars {
	my ($config) = @_;
	my %var;
	open (RCFG, "<$config") or die $!;
	while (<RCFG>){
		chomp;
		# name = value (optional '/"/;/#, ignores commented examples)
		if (m!^\$?([^ #/='";]+) ?= ?['"]?([^#='";]+)['"]?;? ?$!){
			my $name = $1;
			my $value = $2;
			$value =~ s!\s+$!!;
			$value =~ s!^yes!1!; # yes > 1 - true
			$value =~ s!^no!0!; # no > 0 - false
			$value =~ s!, ?!|!g; # list - comma > pipe (script specific)
			if ($name eq 'PPWebUrl' and $value !~ m!^/! and $var{'HomeUrl'}){
				$value = "$var{'HomeUrl'}$value";
			}
			elsif ($name =~ m!(Dir|Url)$! and $value !~ m!^/! and $var{"PPWeb$1"}){
				my $dir = $var{"PPWeb$1"};
				$value = "$dir/$value";
			}
			elsif ($name =~ m!(Data|Log|Script)$! and $value !~ m!^/! and $var{"$1Dir"}){
				my $dir = $var{"$1Dir"};
				$value = "$dir/$value";
			}
			elsif ($name =~ m!Cgi$! and $value !~ m!^/! and $var{'CgiUrl'} ){
				$value = "$var{'CgiUrl'}/$value";
			}
			elsif ($name =~ m!File$! and $value !~ m!^/! and $var{'DataDir'}){
				$value = "$var{'DataDir'}/$value";
			}
			#elsif ($name eq 'SkipLabels'){
			#	$value =~ s!\|Rn\|!|R4|R5|R6|RC|!;
			#}
			$var{$name} = $value;
		}
		#$Categories=array('', 'Video', 'Music/New', 'Download', 'Download/New', 'Video/Sample');
# 		elsif (m!^\$?([^ #/='";]+) ?= ?((?:array ?)?\([^#=";\)]+\));? ?$!){
# 			my $name = $1;
# 			my $value = $2;
# 			$var{$name} = $value;
# 		}
		# 'name = (value)' or '# name = value' > undef (optional '";)
		elsif (m!^(?:#|//)? ?([^ /='";]+) ?= ?['"]?([^#='";]+)?['"]?;? ?$!){
			# already have name w/ value or its a commented var w/ no value
			# want to ignore commented vars w/ no value?
			unless ($var{$1} or m!^(?:#|//).+= ?$!){ 
				$var{$1} = '';
			}
		}
	}
	close RCFG or warn $!;
	unless ($var{'Host'}){ $var{'Host'} = $ENV{'SERVER_NAME'}; }
	#unless ($var{'Host'}){ $var{'Host'} = $ENV{'HTTP_HOST'}; }
	if ($var{'Nice'}){ $var{'Nice'} .= ' '; }
	return %var;
}

sub HtmHead { # not needed by nzbgetpp.pl
	my ($page_title, $message, $return_link, $return_title, $related_links) = @_ ; 
	# not always sent, fixme
	unless ($related_links){ $related_links = ''; } 
	unless ($message){ $message = ''; }
	my $r = 'Go to:&nbsp;';
	if ($return_title and $return_title ne 'Return to NzbgetWeb' and $return_link){
		$return_title =~ s!Return to !!;
		$return_title =~ s!index!PPWeb!;
		$return_link =~ s!.+index\.html!$VAR{'HomeUrl'}index.html!;
		$return_link =~ s!^$VAR{'HomeUrl'}$!$VAR{'HomeUrl'}index.html!;
		$r = 'Return&nbsp;to&nbsp;<A HREF="'.$return_link.'">'.$return_title.'</A>&nbsp;&nbsp;Go to:&nbsp;';
	}
	
	my $h = '';
	if ($VAR{'HomeName'} eq 'NzbgetWeb'){
		$h = '<A HREF="'.$VAR{'HomeUrl'}.'nzbgetweb/">NzbgetWeb</A>';
	}
# 	elsif ($VAR{'HomeName'} eq 'Popular'){
# 		$h = '<A HREF="'.$VAR{'HtmlUrl'}.'/popular.html">Popular</A>';
# 	}
	elsif ($VAR{'HomeName'} eq 'NZBGet'){
		$h = '<A HREF="'.$VAR{'Protocol'}.$VAR{'uiHost'}.'">NZBGet</A>';
	}
# 	else {
# 		$h = '<A HREF="'.$VAR{'HomeUrl'}.'index.html">'.$VAR{'HomeName'}.'</A>';
# 	}
	$h .= '&nbsp;&nbsp;<A HREF="'.$VAR{'HomeUrl'}.'index.html">PPWeb</A>';	
# 	if ($return_title eq 'NzbgetWeb'){
# 		$return_title = 'Return to NzbgetWeb';
# 		$return_link = $VAR{'HomeUrl'}.'nzbgetweb/';
# 		$r ='<div class="block"><A HREF="'.$return_link.'">'.$return_title.'</A>';
# 	}
# 	elsif ($return_title eq 'NZBGet' and $VAR{'uiHost'}){
# 		$return_title = 'Return to NZBGet';
# 		$return_link = $VAR{'uiHost'};
# 		$r ='<div class="block"><A HREF="'.$return_link.'">'.$return_title.'</A>';
# 	}
# 	elsif ($return_title eq 'PPWeb'){
# 		$return_title = 'Return to PPWeb';
# 		$return_link = $VAR{'HomeUrl'}.'index.html';
# 		$r ='<div class="block"><A HREF="'.$return_link.'">'.$return_title.'</A>';
# 	}
qq~<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><TITLE>$page_title</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, no-store, must-revalidate">
<META HTTP-EQUIV="Expires" CONTENT="-1">
<link rel="stylesheet" type="text/css" href="$VAR{'HomeUrl'}nzbgetweb/style.css">
</HEAD><BODY>
<div class="top"><A NAME="top" HREF="http://dalrun.com/Linux/Software/Nzbget/PPWeb/">PPWeb</A></div>
<div class="block">$r$h$related_links</div>
<table width="100%"><tr><td valign="top"><div class="block">
<h2>$page_title</h2>
$message
~;
}

sub HtmReturn { # not needed by nzbgetpp.pl
	my ($return) = @_; # html name : a name
	my $return_link;
	my $a_name = 0;
	
	if (!$return or $return eq "$VAR{'HomeName'}:0" or $return eq $VAR{'HomeName'}) { 
		if ($VAR{'HomeName'} eq 'NzbgetWeb'){
			$return_link = $VAR{'HomeUrl'}.'nzbgetweb/';
		}
		# need to get from nzbget.conf?# TODO URL/Port
		elsif ($VAR{'HomeName'} eq 'NzbGet'){
# 			$return_link = $VAR{'Host'};
# 			$return_link =~ s!$VAR{'Host'}(:\d+)?!$VAR{'Host'}:6789!;
			$return_link = 'http://192.168.1.1:6788';
		}
		# ppweb index.html
		else { $return_link = $VAR{'HomeUrl'}; }
		$return = $VAR{'HomeName'}; 
		#$return_link = $VAR{'HomeUrl'};
	}
	elsif ($return =~ s!:(\d+)$!!){
		$a_name = $1;
		if ($return eq 'hold'){
			$return_link = "$VAR{'CgiUrl'}/nzbget_ppweb.cgi?hold#$a_name";
		}
		elsif ($return eq 'save'){
			$return_link = "$VAR{'CgiUrl'}/nzbget_ppweb.cgi?save";
		}
		else { $return_link = "$VAR{'HtmlUrl'}/$return.html#$a_name"; }
	}
	elsif ($return eq 'hold'){
		$return_link = "$VAR{'CgiUrl'}/nzbget_ppweb.cgi?hold";
	}
	elsif ($return eq 'download'){
		$return_link = "$VAR{'CgiUrl'}/nzbget_ppweb.cgi?list";
	}
	elsif ($return eq 'save'){
		$return_link = "$VAR{'CgiUrl'}/nzbget_ppweb.cgi?save";
	}
	elsif ($return eq 'TV'){
		$return_link = "$VAR{'WfCgi'}?watchlist#TV";
	}
	elsif ($return =~ m!\.html$!){
		$return_link = "$VAR{'HtmlUrl'}/$return";
	}
	elsif (-e "$VAR{'HtmlDir'}/$return.html"){
		$return_link = "$VAR{'HtmlUrl'}/$return.html";
	}
	elsif (-e "$VAR{'PPWebDir'}/$return.html"){
		$return_link = "$VAR{'PPWebUrl'}/$return.html";
	}
	# so far only testing in nzbget_ppweb.cgi
# 	elsif ($return =~ m!_!){
# 		$return_link = "$VAR{'HtmlUrl'}/$return.html";
# 	}
	return ($return, $a_name, $return_link);
}

sub HtmRelated { # not needed by nzbgetpp.pl
	my ($name, $site, $re) = @_;
	my $spaces = '&nbsp;&nbsp;';
	my $related_links = '';
	
	if ($name =~ m!\.log!){
		$related_links .= $spaces.'Logs:&nbsp;';
		opendir(DIR, $VAR{'LogDir'}) or die $!;
		my @logs = readdir(DIR);
		closedir(DIR) or warn $!;
		foreach (sort {lc $a cmp lc $b} @logs) { 
			if (m!^(.+)\.log$!i){
				my $l_name = $1;
				#&Print ("  $name $l_name", 4, 0);
				if ($name =~ m!$l_name!i){#.'log' eq $name){
					$related_links .= '<B class="DEBUG">'.$l_name.'</B>&nbsp;';
				}				
				elsif ($re){
					$related_links .= "<A HREF=\"$VAR{'WfCgi'}?tail_log=$l_name.log&amp;re=$re\">$l_name</A>&nbsp;";
					
				}
				else {
					$related_links .= "<A HREF=\"$VAR{'WfCgi'}?tail_log=$l_name.log\">$l_name</A>&nbsp;";
				}
			}
		}
		if (-e "$VAR{'HtmlDir'}/dev.txt"){
			$related_links .= "<A HREF=\"$VAR{'HtmlUrl'}/dev.txt\">dev.txt</A>&nbsp;";
		}
		if ($VAR{'NzbgetLog'} ne $VAR{'LogDir'}.'/nzbget.log' and $VAR{'NzbgetLog'} =~ m!^/.+!){
			$related_links .= "<A HREF=\"$VAR{'WfCgi'}?tail_log=nzbget.log\">nzbget</A>&nbsp;";
		}
		#$related_links .= "&nbsp;&nbsp;&nbsp;";
		if ($name =~ m!^tail (.+)!){
			my $log = $1;
			if ($log eq 'error.log'){
				$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?view_log=$log\">View Full Log</A>";
			}
			else {
				$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?view_log=$log\">Trim/View Full Log</A>";
			}
		}
	}
	elsif ($name eq 'down_hold'){
		if ($re){
			$related_links = $spaces.'Downloads:&nbsp;<B class="DEBUG">On Hold</B>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?list&amp;re='.$re.'">In Progress</A>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?save&amp;re='.$re.'">Complete</A>';
		}
		else {
			$related_links = $spaces.'Downloads:&nbsp;<B class="DEBUG">On Hold</B>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?list">In Progress</A>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?save">Complete</A>';
		}
	}
	elsif ($name eq 'down_list'){
		if ($re){
			$related_links = $spaces.'Downloads:&nbsp;<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?hold&amp;re='.$re.'">On Hold</A>'.$spaces.'<B class="DEBUG">In Progress</B>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?save&amp;re='.$re.'">Complete</A>';
		}
		else {
			$related_links = $spaces.'Downloads:&nbsp;<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?hold">On Hold</A>'.$spaces.'<B class="DEBUG">In Progress</B>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?save">Complete</A>';
		}
	}
	elsif ($name eq 'down_save'){
		if ($re){
			$related_links = $spaces.'Downloads:&nbsp;<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?hold&amp;re='.$re.'">On Hold</A>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?list&amp;re='.$re.'">In Progress</A>'.$spaces.'<B class="DEBUG">Complete</B>';
		}
		else {
			$related_links = $spaces.'Downloads:&nbsp;<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?hold">On Hold</A>'.$spaces.'<A HREF="'.$VAR{'CgiUrl'}.'/nzbget_ppweb.cgi?list">In Progress</A>'.$spaces.'<B class="DEBUG">Complete</B>';
		}
	}
	elsif ($name eq 'Watch List'){ # TODO
		$related_links .= $spaces;
	}
	else {
		#$related_links = 'Go to:';
# 		if (-e "$VAR{'HtmlDir'}/Nzbsrus_$VAR{'NR_Default'}.html"){
# 			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Nzbsrus_$VAR{'NR_Default'}.html\">NzbsRus</A>";
# 		}
# 		elsif ($VAR{'NR_Default'}) { 
# 			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Nzbsrus_browse\">NzbsRus</A>";
# 		}
		if (-e "$VAR{'HtmlDir'}/Nzbsorg_$VAR{'NO_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Nzbsorg_$VAR{'NO_Default'}.html\">Nzbsorg</A>";
		}
		elsif ($VAR{'NO_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Nzbsorg_browse\">Nzbsorg</A>";
		}
# 		if (-e "$VAR{'HtmlDir'}/Kerews_$VAR{'KW_Default'}.html"){
# 			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Kerews_$VAR{'KW_Default'}.html\">Kerews</A>";
# 		}
# 		elsif ($VAR{'KW_Default'}) { 
# 			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Kerews_browse\">Kerews</A>";
# 		}
		if (-e "$VAR{'HtmlDir'}/Nzbsin_$VAR{'NI_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Nzbsin_$VAR{'NI_Default'}.html\">Nzbsin</A>";
		}
		elsif ($VAR{'NI_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Nzbsin_browse\">Nzbsin</A>";
		}
		if (-e "$VAR{'HtmlDir'}/Pwnzb_$VAR{'PN_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Pwnzb_$VAR{'PN_Default'}.html\">Pwnzb</A>";
		}
		elsif ($VAR{'PN_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Pwnzb_browse\">Pwnzb</A>";
		}
		if (-e "$VAR{'HtmlDir'}/Nzbtv_$VAR{'NT_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Nzbtv_$VAR{'NT_Default'}.html\">Nzbtv</A>";
		}
		elsif ($VAR{'NT_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Nzbtv_browse\">Nzbtv</A>";
		}
		if (-e "$VAR{'HtmlDir'}/Nzbsu_$VAR{'NS_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Nzbsu_$VAR{'NS_Default'}.html\">Nzbsu</A>";
		}
		elsif ($VAR{'NS_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Nzbsu_browse\">Nzbsu</A>";
		}
		if (-e "$VAR{'HtmlDir'}/Dognzb_$VAR{'DN_Default'}.html"){
			$related_links .= "$spaces<A HREF=\"$VAR{'HtmlUrl'}/Dognzb_$VAR{'DN_Default'}.html\">Dognzb</A>";
		}
		elsif ($VAR{'DN_Default'}) { 
			$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?do=Dognzb_browse\">Dognzb</A>";
		}
	}
	if ($site){ 
		#my $page_title = $site.' '.$name;
		$related_links .= $spaces.'Page:&nbsp;<A HREF="'.$VAR{'WfCgi'}.'?do='.$site.'_seen&amp;sc='.$name.'">mark read</A>';
		$related_links .= $spaces.'<A HREF="'.$VAR{'WfCgi'}.'?delete_html='.$site.'_'.$name.'.html">delete</A>';
		$related_links .= $spaces.$site.':&nbsp;<A HREF="'.$VAR{'WfCgi'}.'?do='.$site.'_update">update</A>';
		$related_links .= $spaces.'<A HREF="'.$VAR{'HomeUrl'}.'nzbgetweb/config.php?section=P-WF%20'.$site.'">configure</A>';
	}
# 	elsif ($name !~ m!\.log! and $name ne 'Watch List'){
# 		$related_links .= "$spaces<A HREF=\"$VAR{'WfCgi'}?watchlist\">Watch List</A>$spaces<A HREF=\"$VAR{'WfCgi'}?tail_log=ppweb.log\">Logs</A>";
# 	}
	return $related_links;
}

sub HtmFoot {  # not needed by nzbgetpp.pl
	my ($return_link, $return_title, $menu, $related_links) = @_ ;
	unless ($related_links){ $related_links = ''; }
	my $r = 'Go to:&nbsp;';
	if ($return_title and $return_title ne 'Return to NzbgetWeb' and $return_link){
		$return_title =~ s!Return to !!;
		$return_title =~ s!index!PPWeb!;
		$return_link =~ s!.+index\.html!$VAR{'HomeUrl'}index.html!;
		$return_link =~ s!^$VAR{'HomeUrl'}$!$VAR{'HomeUrl'}index.html!;
		$r = 'Return&nbsp;to&nbsp;<A HREF="'.$return_link.'">'.$return_title.'</A>&nbsp;&nbsp;Go to:&nbsp;';
	}
	
# 	my $h = '<A HREF="'.$VAR{'HomeUrl'}.'index.html">PPWeb</A>&nbsp;<A HREF="'.$VAR{'HomeUrl'}.'nzbgetweb/">NzbgetWeb</A>';
# 	if ($VAR{'uiHost'}){
# 		$h .= '&nbsp;<A HREF="http://'.$VAR{'uiHost'}.'">NZBGet</A>';
# 	}
	my $h = '';
	if ($VAR{'HomeName'} eq 'NzbgetWeb'){
		$h = '<A HREF="'.$VAR{'HomeUrl'}.'nzbgetweb/">'.$VAR{'HomeName'}.'</A>';
	}
	elsif ($VAR{'HomeName'} eq 'NZBGet' and $VAR{'uiHost'}){
		$h = '<A HREF="'.$VAR{'Protocol'}.$VAR{'uiHost'}.'">NZBGet</A>';
	}
# 	elsif ($VAR{'HomeName'} eq 'Popular'){
# 		$h = '<A HREF="'.$VAR{'HtmlUrl'}.'/popular.html">Popular</A>';
# 	}
# 	else {
# 		$h = '<A HREF="'.$VAR{'HomeUrl'}.'index.html">PPWeb</A>';
# 	}
	$h .= '&nbsp;&nbsp;<A HREF="'.$VAR{'HomeUrl'}.'index.html">PPWeb</A>';	
# 	unless ($menu){
# 		open (TXT, '<', $VAR{'HtmlDir'}.'/menu.txt') or &Print ('  Could not open: '.$VAR{'HtmlDir'}.'/menu.txt, '.$!.' (HF01)', 1, 0);
# 		$menu = <TXT>;
# 		close TXT or warn $!;
# 	}
qq~
</div><div class="block">$r$h$related_links&nbsp;&nbsp;&nbsp;<A NAME="foot" HREF="#top">top</A></div>
</td><td valign="top">
$menu
</td></tr></table>
</BODY></HTML>
~;
}

sub HtmError { # not needed by nzbgetpp.pl
	my ($message) = @_ ;
	print "Content-type: text/html\n\n";
	print qq~<HTML><HEAD><TITLE>Error</TITLE>
		<link rel="stylesheet" type="text/css" href="$VAR{'HomeUrl'}style.css">
		</HEAD><BODY><div class="top"><A HREF="http://dalrun.com/Linux/Software/Nzbget/PPWeb/">PPWeb</A></div>
		<div class="block"><A HREF="$VAR{'HomeUrl'}index.html">Return to $VAR{'HomeName'}</A></div>
		<div class="block"><h3>Error</h3><P>$message</P></div>
		<div class="block"><A HREF="$VAR{'HomeUrl'}index.html">Return to $VAR{'HomeName'}</A></div>
		</BODY></HTML>
	~;
	exit;
}

sub HtmLog { # not needed by nzbgetpp.pl only called once by wfnzb.cgi and by/to itself
	my ($log, $type, $return) = @_;
	my $log_dir;
	if (-e "$VAR{'LogDir'}/$log"){
		$log_dir = "$VAR{'LogDir'}";
	}
	else { # see if there's a NameLog VAR
		my $var = $log;
		$var =~ s!^(\w)(\w+)\.log!\u$1$2Log!;
		if ($VAR{"$var"}){
			$log_dir = $VAR{$var};
			$log_dir =~ s!/[^/]+$!!;
		}
		else {
			&Print ("  error: $log not found (FN79)", 1, 1);
		}
	}
	
	#my $related_links = ''; # so we can use it in foot
	my $related_links = &HtmRelated ('tail '.$log, '', $return);

	open (HTM, ">$VAR{'HtmlDir'}/$log.html") or &Print ("  Couldn't open: $VAR{'HtmlDir'}/$log.html, $! (PF0)", 1, 1);
	
	if ($type eq 'tail'){
		open(RLOG, "tail -$VAR{'TailLines'} $log_dir/$log |") or die $!;
		#$related_links = &HtmRelated ("tail $log");
		
		if ($return){
			print HTM &HtmHead ($log, "Last $VAR{'TailLines'} lines.<br><br><A NAME=\"head\" HREF=\"#foot\">Jump to bottom</A><pre><font face=\"Monospace,Courier,Courier New\">", "$VAR{'HtmlUrl'}/$return.html", "Return to $return", $related_links);
		}
		else {
			print HTM &HtmHead ($log, "Last $VAR{'TailLines'} lines.<br><br><A NAME=\"head\" HREF=\"#foot\">Jump to bottom</A><pre><font face=\"Monospace,Courier,Courier New\">", $VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", $related_links);
		}
	}
	elsif ($log eq 'error.log'){
		open(RLOG, "$log_dir/$log") or die $!;
		print HTM &HtmHead ($log, "<A NAME=\"head\" HREF=\"#foot\">Jump to bottom</A><pre><font face=\"Monospace,Courier,Courier New\">", $VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", '');
	}
	else {
		$VAR{'TailLevel'} = $VAR{'LogLevel'};
		&TrimLog ($log); # make related link option instead of forcing?
		open(RLOG, "$log_dir/$log") or die $!;
		print HTM &HtmHead ($log, "<A NAME=\"head\" HREF=\"#foot\">Jump to bottom</A><pre><font face=\"Monospace,Courier,Courier New\">", $VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", '');
	}
	
	if ($log eq 'error.log'){
		while (<RLOG>) {
			s!^(\[\w{3}) \w{3} \d{2} (\d\d:\d\d):\d\d 20\d\d\] \[error\] \[client [^\]]+\]!$1 $2]\t!;
			s!, referer: https?://.+/$!!;
			s!\&!&amp;!g;
			s!<!&lt;!g;
			s!((?:\[[^\]]+\]\t)?[^\n]{130,140}[/( ])!$1\n\t\t  !g; 
			print HTM;
		}
	}
	elsif ($log eq 'status.log'){
		# get nzbs queued/downloading
		my %nzbget;
		my $rt = '';
		open (NZB, "-|", "$VAR{'NzbgetRun'} -L G 2> /dev/null")  or &Print ("  Couldn't open: $VAR{'NzbgetRun'}, $! (PF0)", 1, 1);
		while (<NZB>) { 
			if (m!^\[[\d-]+\](?: \[[\d+-]+\])? ([^\(]+) \(\d+ files, ([\d\.]+ [KMGB]+) \+ ([\d\.]+ [KMGB]+) paused(, \d+ threads)?!i){
				if ($2 eq '0 B' and $3){
					$nzbget{$1} = "$3 paused";
				}
				elsif ($4){
					$nzbget{$1} = "$2 downloading";
				}
				else { $nzbget{$1} = "$2 queued"; }
# 				unless ($2 eq '0 B'){
# 					$nzbget{$1} = "$2 in queue";
# 				}
			}
# 			elsif (m!^\[[\d-]+\] ([^\(]+) \(\d+ files, 0 \+ ([\d\.]+ [KMGB]+) paused!i){
# 				$nzbget{$1} = "$2 (paused)";
# 			}
			elsif (m!^(Remaining time: \d{2}:\d{2}:\d{2})!){
				$rt = "\n$1";
			}
			elsif (m!^(Current download rate: [\d\.]+ [KMGB]+)!){
				$rt .= "\n$1s";
			}	
		}
		close NZB or warn $!;
		
		my $last;
		while (<RLOG>) { 
			# day separation
			if (m!^(\[\w{3} )!){ 
				if ($last and $last ne "$1"){
					print HTM "\n";
					$last = '';
				}
				else { $last = $1; }
			}
			
			my $line = &StatusHtm ($_);
			#if ($line =~ m!^\[\w{3} \d\d:\d\d\] QUEUED\t(.+?) {2,99}(.+)!i){
			if ($line =~ m!^[^\t]+\t(.+?) {2,99}(.+)!i){
				my $title = $1;
				my $left = $2;
				if ($nzbget{$title}){
					$line =~ s!\Q$left\E!$nzbget{$title}!;
				}
			}
			
			print HTM $line; 
		}
		print HTM "$rt\n";
	}
	elsif ($log eq 'dev.log'){
		while (<RLOG>) { 
			print HTM; 
		}
	}
	else {
		my $file;
		while (<RLOG>) {
			s!^(\w{3}) \w{3} [ \d]+ (\d\d:\d\d):\d\d 20\d\d(?:\t\d+)?\t![$1 $2] !;
			s!((?:\[[^\]]+\]\t)?[^\n]{130,140}[/ .])!$1\n\t\t\t  !g; 
			if (m!^[\r\n]!){ next; }
			elsif (m!^total!){ next; }
			elsif (m!^receiving!){ next; }
			elsif (s!^([^:]+)/$!<B class="INFO">INFO</B>\t Remote receiving: $1!){
				$file = $1;
				if ($VAR{'TailLevel'} < 3){ next; }
			}
			elsif ($file and s!^$file/(.+)!<B class="DETAIL">DETAIL</B>\t   Got: $1!){
				if ($VAR{'TailLevel'} < 4){ next; }
			}
			elsif (s!^sent \d+ bytes  r(.+)!<B class="INFO">INFO</B>\t R$1!){
				if ($VAR{'TailLevel'} < 3){ next; }
			}
			elsif (s! \[?INFO\]?\t?! <B class="INFO">INFO</B>\t!){
				if ($VAR{'TailLevel'} < 3){ next; }
			}
			elsif (s! \[?WARNING\]?\t?! <B class="WARNING">WARNING</B>\t!){
				if ($VAR{'TailLevel'} < 2){ next; }
			}
			elsif (s! \[?ERROR\]?\t?! <B class="ERROR">ERROR</B>\t!){}
			elsif (s! \[?DETAIL\]?\t?! <B class="DETAIL">DETAIL</B>\t!){
				if ($VAR{'TailLevel'} < 4){ next; }
			}
			elsif (s! \[?DEBUG\]?\t?! <B class="DEBUG">DEBUG</B>\t!){
				if ($VAR{'TailLevel'} < 5){ next; }
			}
			#elsif ($log ne 'dev.log' and $log ne 'status.log') { next; }
			#else { next; }
			print HTM;
		}
	}
	close RLOG or warn $!; #</tt>
	print HTM "</font></pre>";
	#print HTM &HtmFoot ($VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", $related_links);
	if ($return){
		print HTM &HtmFoot ($VAR{'HtmlUrl'}.'/'.$return.'.html', $return, '', $related_links);
		#print HTM qq~\n</div><div class="block"><A HREF="$VAR{'HtmlUrl'}/$return.html">Return to $return</A>&nbsp;&nbsp;&nbsp;Go to:&nbsp;<A NAME="foot" HREF="#top">top</A>&nbsp;&nbsp;&nbsp;$related_links</div>\n</BODY></HTML>~;
		#print &HtmFoot ($return, "$VAR{'HtmlUrl'}/$return.html", '');
	}
	else {
		print HTM &HtmFoot ('', '', '', $related_links);
# 		my $return_link = $VAR{'HomeUrl'}.'nzbgetweb/';
# # 		if ($VAR{'HomeName'} eq 'to NzbgetWeb'){
# # 			$return_link = $VAR{'HomeUrl'}.'nzbgetweb/';
# # 		}
# 		print HTM qq~\n</div><div class="block"><A HREF="$return_link">Return to $VAR{'HomeName'}</A>&nbsp;&nbsp;&nbsp;Go to:&nbsp;<A NAME="foot" HREF="#top">top</A>&nbsp;&nbsp;&nbsp;$related_links</div>\n</BODY></HTML>~;
		#print &HtmFoot ($VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", '');
	}
	close (HTM) or warn $!;
	#chmod (oct($VAR{'Perms'}), "$VAR{'HtmlDir'}/$log.html");
	#print "Location: $VAR{'Protocol'}$VAR{'Host'}$VAR{'HtmlUrl'}/$log.html#foot\n\n";
}

sub TrimLog { # not needed by nzbgetpp.pl
	my ($log) = @_;
	my $new_log = "$VAR{'LogDir'}/$log.tmp";
	open (WLOG, ">$new_log") or die $!;
	open(RLOG, "tail -$VAR{'LogLines'} $VAR{'LogDir'}/$log |") or die $!;
	while (<RLOG>) {
		print WLOG;
	}
	close WLOG or warn $!;
	rename ("$VAR{'LogDir'}/$log.tmp", "$VAR{'LogDir'}/$log") or die $!;		
	close RLOG or warn $!;
	#chmod (oct($VAR{'Perms'}), "$VAR{'LogDir'}/$log");
}

sub StatusLog { # needed by nzbgetpp.pl
	my ($title, $status, $level, $sub) = @_; # $cat sent in status
	my @block;
	my $num = 0;
	my $mod_line;
	#&Print ("  Updating status log ($sub)", 5, 0);
	open (WTXT, ">$VAR{'StatusLog'}.tmp") or &Print ("  Couldn't open $VAR{'StatusLog'}.tmp, $! (SL01)", 1, 1);
	open (RTXT, "<$VAR{'StatusLog'}") or &Print ("  Couldn't open $VAR{'StatusLog'}, $! (SL02)", 1, 1);
	while (<RTXT>){
		# skip matching title entry in all cases
		if (m!^[^\t]+\t\Q$title\E {2,99}!i){
			$mod_line = $_;
			next;
		}
		# grab select last n lines for NW PP block - not queued.. do as ! m!!?
		# how to track 'HOLD  ', testing
		#elsif ($VAR{'StatusBlock'} and m!(DONE  |FAILED|GOT   |SAMPLE|UNPACK|HOLD  |GONE  )\t!){
		elsif ($VAR{'StatusBlock'} and m!(GONE  |DONE  |FAILED|GOT   |SAMPLE|UNPACK|HOLD  )\t!){
			print WTXT; # as is
			# modify for @block
			my $line = &StatusHtm ($_);
			push (@block, $line);
			# remove from top of block if over configured line num
			if ($num >= $VAR{'StatusBlock'} - 1){ 
				shift(@block);
			}
			else { $num ++; }
		}
		else { print WTXT; }
	}
# 	if ($level eq 'GONE  ' and $mod_line and $mod_line =~ m!(DONE  |QUEUED|GOT   )HOLD  \t$title {2,99}!i){
# 		if ($level eq 'GONE  '
# 		$title = sprintf("%-80s", $title);
# 		print WTXT "[$DateTime[0]] $level\t$title$status\n";
# 	}
# 	elsif
	# print new/changed title entry if it isn't a SAMPLE entry deletion
	#unless ($level eq 'DEL'){ # ### don't think DEL is used anymore
		#printf WTXT "[$DateTime[0]] $level\t%-60s$status\n", $title;
		#$title = sprintf("%-60s", $title);
		# NOTE any changes also need to be done to wfnzb.cgi new_name
		$title = sprintf("%-70s", $title);
		print WTXT "[$DateTime[0]] $level\t$title$status\n";
	#}
	close WTXT or warn $!;
	rename ("$VAR{'StatusLog'}.tmp", "$VAR{'StatusLog'}") or &Print ("  Couldn't rename $VAR{'StatusLog'}.tmp, $! (SL03)", 1, 1);
	close RTXT or warn $!;
	
	# update/rewrite NW PP block - no StatusBlock = no @block
	if (@block){
		#&Print ("  Updating NzbgetWeb status block ($sub)", 5, 0);
		open (WTXT, ">$VAR{'LogDir'}/status.txt") or &Print ("  Couldn't open status.txt, $! (SL04)", 1, 0);
			print WTXT @block;
			#unless ($level =~ m!^(GONE  |QUEUED)$!){ 
			unless ($level =~ m!^QUEUED\*?$!){ 
			#unless ($level eq 'DEL   '){ 
				#$title = sprintf("%-60s", $title);
				$title = sprintf("%-70s", $title);
				my $line = &StatusHtm ("[$DateTime[0]] $level\t$title$status");
				print WTXT "$line\n";
			}
		close WTXT or warn $!;
	}
	# remove downloaded movies from watchlist
	if ($level eq 'DONE  ' and $title =~ m!(.+) (19[3-9]\d|20[01]\d)!){
		my $tt = $1;
		my $yr = $2;
		&Print ("  Removing from Watch list ($sub)", 5, 0);
		open (WTXT, ">$VAR{'WatchFile'}.tmp") or die $!;
		open (RTXT, "<$VAR{'WatchFile'}") or die $!;
		while (<RTXT>){
			if (m!^# queued (?:.+, )?\Q$tt\E(?:, .+)?\t$yr!){
				next;
			}
			else { print WTXT; }
		}
		close WTXT or warn $!;
		rename ("$VAR{'WatchFile'}.tmp", "$VAR{'WatchFile'}") or die $!;		
		close RTXT or warn $!;
	}
}

sub StatusHtm { # not needed by nzbgetpp.pl
	my ($line) = @_;
	# TODO get rid of hard link - add old script to conf or finish transfer to wfnzbon hold
	# delayed remote extraction link
	if ($line =~ m!GOT   \t(.+?) {3,99}(.+\(($VAR{'Categories'})\))$! and -e "$VAR{'DestDir'}/$3/$1/$1.sh"){
		my $desc = $2;
		my $link = "$VAR{'DestDir'}/$3/$1";
		$link =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
		$line =~ s!\Q$desc\E!<A HREF="$VAR{'CgiUrl'}/nzbget_ppweb.cgi?dst_mv%20$link">process</A>!;
	}
	# resume/delete sample
	elsif ($line =~ m!SAMPLE\t(.+?) {3,99}(.+\(($VAR{'Categories'})\))$! and -e "$VAR{'DestDir'}/$3/$1"){ # e.g. download/Video/Sample/title
		my $title = "$1 $3"; # title cat e.g. Video/Sample
		my $desc = $2; # status cat e.g. on hold (Video/Sample)
		$title =~ s!/Sample$!!; # queue/delete links use base cat
		$title =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
		$line =~ s!\Q$desc\E!<A HREF="$VAR{'CgiUrl'}/nzbget_ppweb.cgi?queue $title">resume</A>&nbsp;&nbsp;&nbsp;<A HREF="$VAR{'CgiUrl'}/nzbget_ppweb.cgi?delete $title">delete</A>!;
	}
	# on hold
	elsif ($line =~ m!HOLD  \t.+? {3,99}(.+)$!){
		my $desc = $1;
		$line =~ s!\Q$desc\E!<A HREF="$VAR{'CgiUrl'}/nzbget_ppweb.cgi?hold">on hold</A>!;
	}
	elsif ($line =~ s!DONE  \t!<B class="INFO">DONE  </B>\t!){}
	elsif ($line =~ s!GONE  \t!<B class="INFO">GONE  </B>\t!){}
	#elsif ($line =~ s!UNPACK\t!<B class="INFO">UNPACK</B>\t!){}
	elsif ($line =~ s!FAILED\t!<B class="ERROR">FAILED</B>\t!){}
	
	return $line;
}

sub UpdateDb { # used by nzbgetpp.pl... and wfnzb
	my ($title, $type, $down_log, $cat, $sub, $o_title) = @_; # type = nzb, got, etc. $down_log can be remote $cat for status
	my @log;
	my $found = 0;
	my $db_title = $title;
	$db_title =~ s! S0?(\d+)E(\d+)! $1$2!i;
	$db_title =~ s! (\d+)X(\d+)! $1$2!i;
	#open (WDB, ">$down_log.tmp")  or &Print ("  Couldn't open: $down_log.tmp, $! ($sub)", 1, 1);
	open (RDB, "<$down_log")  or &Print ("  Couldn't open: $down_log, $! ($sub)", 1, 1);
	while (<RDB>){
		chomp;
		if (m!^\Q$db_title\E\t(TvHold|VidHold|nzb|queued|sampled|resumed|ignore|seen|got)(\*)?!){
			my $o_type = $1;
			my $o_flag = ''; # so we can append empty value to $type when it adds the got fix flag (or neither $type or the db has a got fix flag)
			if ($2){ 
				$o_flag = $2; # $type has no flag and we want too keep the db flag it added earlier (the only time $o_flag has a value)
			}
			$_ =~ s!^\Q$db_title\E\t$o_type(?:\*)?!$db_title\t$type$o_flag!;
			$found = 1;
			&Print ("  Updated Db: $db_title ($o_type$o_flag > $type$o_flag) ($sub)", 4, 0);
		}
		push (@log, $_);
		#print WDB;
	}
	#close WDB or warn $!;
	#rename ("$down_log.tmp", "$down_log") or die $!;		
	close RDB or warn $!;
	
	# testing adding orig title to db - currently only sent by sites.pm, so need to initialize
	unless ($o_title){ $o_title = ''; }
	# if we didn't edit an existing entry, add a new entry to the db array
	unless ($found){
		push (@log, "$db_title\t$type\t\t$o_title");
		&Print ("  Adding to Db: $db_title ($type) ($sub)", 4, 0);
	}
	
	# rewriting db - ### so why did we write it above instead of just reading it????????... removed write
	open (WDB, ">$down_log")  or &Print ("  Couldn't open: $down_log, $! ($sub)", 1, 1);
	foreach my $file (sort {lc $a cmp lc $b} @log) { 
		print WDB "$file\n";
	}
	close (WDB) or warn $!;
	
	if (!$IsRemote and $cat and $VAR{'StatusLog'} and $type =~ m!^(TvHold|VidHold|nzb|sampled|queued|resumed)(?:\*)?$!){ # remote sends no cat
		if ($cat eq 'nzb'){ $cat = '/'; } # 1-2012 print / instead of nzb - part of trying 'nzb' in dbcats
		if ($1 eq 'nzb'){
			&StatusLog ($title, 'have nzb', 'HOLD', 'UD01');
		}
		elsif ($1 eq 'TvHold'){
			&StatusLog ($title, 'TVHold nzb', 'HOLD', 'UD01'); 
		}
		elsif ($1 eq 'VidHold'){
			&StatusLog ($title, 'VidHold nzb', 'HOLD', 'UD01'); 
		}
		elsif ($1 eq 'sampled'){
			&StatusLog ($title, "on hold ($cat)", 'SAMPLE', 'UD01'); 
		}
		elsif ($1 eq 'queued'){
			&StatusLog ($title, "queued ($cat)", 'QUEUED', 'UD01'); 
		}
		elsif ($1 eq 'resumed'){
			&StatusLog ($title, "resumed ($cat)", 'QUEUED', 'UD01'); 
		}
		else { &StatusLog ($title, "UpdateDb error", 'FAILED', 'UD01'); }
		# may be covered elsewhere - i.e. is overwritten and pointless
		#else { &StatusLog ($title, $cat, 'sample downloaded', 'SAMPLE'); }
		#else { &StatusLog ($title, "sample done ($cat)", 'SAMPLE'); }
	}
}

sub DateTime {
	my @mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	my @days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	#my ($min,$hour,$mday,$lmon,$wday) = (localtime)[1,2,3,4,6];
	#my ($min,$hour,$mday,$lmon,$year,$wday) = (localtime)[1,2,3,4,5,6];
	my ($min,$hour,$mday,$lmon,$year,$wday,$yday) = (localtime)[1,2,3,4,5,6,7];
	$year += 1900;
	#             2012             8 (0-11 + 1)           27
	#my $c_days = ($year * 365) + (($lmon + 1) * 30) + $mday;
	# $yday is the day of the year, in the range 0..364 (or 0..365 in leap years.)
	my $c_days = ($year * 365) + $yday;
	$hour = sprintf("%02d", $hour);
	$min = sprintf("%02d", $min);
	$mday = sprintf("%02d", $mday);
	#$lmon = sprintf("%02d", $lmon);
	#                Mon          23:20      8          Aug       09 2012     738612
	@DateTime = ("$days[$wday] $hour:$min", $lmon, "$mon[$lmon] $mday $year", $c_days);
	
	# shell time in seconds since 1970-01-01 (Unix epoch) = $ date +"%s"
	# exec "date +%s";
	
	# my $time = time;  # epoch timestamp, can be converted using locatime (following example)
	#...
	# my ($sec, $min, $hour, $day, $month, $year) = (localtime($time))[0,1,2,3,4,5];
	#...
	
	# print scalar localtime(946684800); # convert epoch > Sat Jan 1 01:00:00 2000 (in my timezone).
}

sub Print { # only two print location's in this lib are here
	my ($message, $log_level, $done) = @_;
	
	if ($IsRemote and $log_level <= $VAR{'LogLevel'}){ # prints to remote log
		if ($VAR{'ScriptLog'}){
			print "[$DateTime[0]] [$LogType[$log_level]]\t$message\n";
		}
		else { print "[$LogType[$log_level]] $message\n"; }
	}
	elsif ($VAR{'ScriptLog'} and ($VAR{'Host'} or @ARGV) and $log_level <= $VAR{'LogLevel'}) { 
		push (@Log, "[$DateTime[0]] $LogType[$log_level]\t$message\n");
		if ($VAR{'NzbgetLevel'}){
			if ($VAR{'Host'} and $log_level <= $VAR{'NzbgetLevel'}) {
				system qx($VAR{'NzbgetRun'} -W $LogChar[$log_level] "$message" > /dev/null);
			}
			elsif (@ARGV and $log_level <= $VAR{'NzbgetLevel'}) {
				print "[$LogType[$log_level]] $message\n"; 
			}
		}
		if ($done and !$ARGV[0]) { print "Location: $VAR{'Protocol'}$VAR{'Host'}$VAR{'HomeUrl'}\n\n"; }
	}
	# appears to be leftover, ie not used
# 	elsif (@ARGV and $ARGV[0] =~ m!^(Nzbsrus|Nzbmatrix)_auto!){
# 		system qx($VAR{'NzbgetRun'} -W $LogChar[$log_level] "$message" > /dev/null);
# 	}
	elsif ($VAR{'Host'}){
		system qx($VAR{'NzbgetRun'} -W $LogChar[$log_level] "$message" > /dev/null);
		if ($done) { 
			if ($VAR{'HaveHeader'}){
				print "<P><B>$message</B></P>";
				print &HtmFoot ($VAR{'HomeUrl'}, "Return to $VAR{'HomeName'}", '');
			}
			else { print "Location: $VAR{'Protocol'}$VAR{'Host'}$VAR{'HomeUrl'}\n\n"; }
		}
	}
	elsif ($message){ # console or nzbget.log (why there's no tab)
		print "$LogType[$log_level] $message\n";
	}
	
	if ($done){
		if ($VAR{'ScriptLog'} and @Log){ 
			open (WLOG, ">>$VAR{'ScriptLog'}") or &Print ("  Couldn't open: $VAR{'ScriptLog'}, $! (pm22)", 1, 1);
			print WLOG @Log;
			close WLOG or warn $!;
		}
		# early exit due to errors/failures - typically 'couldn't open', rename, etc. failures
		if ($done == 1) { 
			my $title = $message;
			if ($title =~ s!.+\(([^)]+)\)[,.].+!$1!){
				if ($IsRemote and -e "$VAR{'RemoteDest'}/remote.log"){ # move download log
					&Print ("  PP for $title failed (early exit)", 1, 0);
					&Print ("  Sending updated remote.log to NZBGet host  (Po70)", 4, 0);
					system qx(scp -pq \"$VAR{'RemoteDest'}/remote.log\" \"$VAR{'NzbgetPC'}:$VAR{'LogDir'}\") or &Print ("  Couldn't SCP $VAR{'NzbgetPC'}, $! (Po70)", 1, 0);
					if (system ("ssh $VAR{'NzbgetPC'} '$VAR{'ScriptDir'}/nzbgetpp.pl' remote_merge") == 0){# or &Print ("  Couldn't SSH $VAR{'NzbgetPC'}, $! (Po70)", 1, 0);
						#&Delete ($VAR{'RemoteDest'}, 'remote.log', 'Po61');
					}
					system qx(ssh $VAR{'NzbgetPC'} '$VAR{'NzbgetRun'} -W E "PP for $title failed (early exit)" > /dev/null') or &Print ("  Couldn't SSH $VAR{'NzbgetPC'}, $! (PO71)", 1, 0);
					#exit 94; how to send to nzbget pc? 3 2012
				}
				else { 
					if ($VAR{'StatusLog'}){ &StatusLog ($title, "PP early exit", 'FAILED'); }
					&Print ("  PP failed (early exit)", 1, 0);
					if ($VAR{'SendEmail'} and $VAR{'EmailTo'} and $VAR{'EmailFrom'} and $VAR{'Sendmail'}){
						if (open (MAIL, "|$VAR{'Sendmail'} -t")){
							print MAIL "To: $VAR{'EmailTo'}\n";
							print MAIL "From: $VAR{'EmailFrom'}\n";
							print MAIL "Subject: [PPWeb] $title failed\n\n";
							print MAIL "PostProcess for $title failed (early exit)\n";
							close (MAIL);
						}
						else { &Print(" Cannot open $VAR{'Sendmail'} - $!, you probably have the wrong path set (Po77)", 1, 0); }
					}
				} 
			}
			exit 94; # addded 94 3 2012
		}
		# planed early exits - all OK
		elsif ($done == 2){ exit; }
		# nzbget return codes for PP (nzbgetpp.pl)
		elsif ($done == 91){ exit 91; } # request nzbget par-check/repair for current collection (92 = all)
		elsif ($done == 93){ exit 93; } # successfull
		elsif ($done == 94){ exit 94; } # failed
# 		my $status = $VAR{'Fail'};
# 		if ($status){ $status = 'E "PP failed"'; } else { $status = 'I "PP success"'; }
# 		system qx($VAR{'NzbgetRun'} -W $status > /dev/null)
	}
}

sub Save {
	my ($dir, $name, $ext, $new_dir, $new_name, $new_ext, $sub) = @_; # $new_name can = $name
	my $short_dir = $new_dir;
	$short_dir =~ s!.+/([^/]+)$!$1!;
	if (-e "$new_dir/$new_name.$new_ext"){
		&Print ("  Renaming would overwrite: $short_dir/$new_name.$new_ext ($sub)", 2, 0);
	}
	else {  # FIXME quit sending dir w/ name (new_name = dir/name)
		if ($new_name =~ m!(.+)/[^\/]+!){
			my $sub_dir = $1;
			unless (-e "$new_dir/$sub_dir"){
				&MakeDir ("$new_dir/$sub_dir", $sub);
			}
		}
		use File::Copy;
		if (move ("$dir/$name.$ext", "$new_dir/$new_name.$new_ext")){
			$ext =~ s!nzb_processed!nzb!;
			if ($sub eq 'DA4'){ # saving rars = detail logging (total number saved = info)
				&Print ("  Saved $new_ext: $short_dir/$new_name.$new_ext ($sub)", 5, 0); 
			}
			else { &Print ("  Saved $new_ext: $short_dir/$new_name.$new_ext ($sub)", 4, 0); }
			if ($VAR{'SavePerms'} and $new_dir =~ m!^$VAR{'SaveDir'}!){
				if (chmod (oct($VAR{'SavePerms'}), "$new_dir/$new_name.$new_ext")){
					&Print ("  Set $VAR{'SavePerms'} perms for: $new_name.$new_ext ($sub)", 5, 0);
				}
			}
		}
		else {
			&Print ("  Couldn't rename $ext: $dir/$name.$ext > $new_dir/$new_name.$new_ext ($sub)", 1, 0);
			unless (-e "$new_dir"){
				&Print ("  Missing directory: $new_dir ($sub)", 1, 0);
			}
		}
	}
}

sub Delete { # for files or empty directories
	my ($dir, $file, $sub) = @_;
	my $short_path = $dir;
	$short_path =~ s!^$VAR{'PPWebDir'}!!;
	if ($file and unlink ("$dir/$file")){
		&Print ("  Deleted: $short_path/$file ($sub)", 4, 0);
# 		if ($file =~ m!\.(rar|r\d+|\d\d+)$!i or $sub eq 'EN24'){ # \d+ matches .1, so \d\d+
# 			&Print ("  Deleted: $short_dir/$file ($sub)", 4, 0);
# 		}
# 		else {&Print ("  Deleted: $short_dir/$file ($sub)", 3, 0);} # all others get INFO log level
	}
	elsif ($file) { &Print ("  Couldn't delete: $short_path/$file ($sub)", 1, 0); }
	elsif (rmdir ($dir)){
		&Print ("  Deleted: $short_path ($sub)", 4, 0);
	}
	else { &Print ("  Couldn't delete dir: $short_path is not empty ($sub)", 1, 0); }

}

sub MakeDir { # MakeTree
	my ($dir, $sub) = @_;
	my $short_path = $dir;
	$short_path =~ s!^$VAR{'PPWebDir'}!!;
	use File::Path;
	if (mkpath ($dir)){
		&Print ("  Created dir: $short_path ($sub)", 4, 0);
		if ($VAR{'SavePerms'} eq '0666' and $dir =~ m!^$VAR{'SaveDir'}!){
			if (chmod (0777, $dir)){
				&Print ("  Set 777 perms for: $short_path ($sub)", 5, 0);
			}
		}
		
	} 
	else { &Print ("  Couldn't create dir: $short_path ($sub)", 1, 1); }
}
	
sub DelTree {
	my ($dir, $sub_dir, $sub) = @_;
	if ($sub_dir){ $dir = "$dir/$sub_dir"; }
	my $short_path = $dir;
	$short_path =~ s!^$VAR{'PPWebDir'}!!;
	use File::Path;
	if (rmtree ($dir)){
		&Print ("  Deleted dir: $short_path ($sub)", 4, 0);
	} 
	else { &Print ("  Couldn't delete dir: $short_path ($sub)", 1, 0); }
}

1;